/**
 *  @file collisionDetector.cpp
 *
 *  @date 19-nov-2009
 *  @author Ives van der Flaas
 */

#include "collisionDetector.h"
#include "circularBoundingBox.h"
#include "notYetImplementedException.h"
#include <typeinfo>

bool si::CollisionDetector::collision(
							std::tr1::shared_ptr<BoundingBox> b1,
							std::tr1::shared_ptr<BoundingBox> b2) const
{
	// Yes, I am using RTTI. I have thought about this and there is
	// no superior way. It's not that bad.

	BoundingBox* bb1 = b1.get();
	BoundingBox* bb2 = b2.get();

	if(typeid(*bb1) == typeid(*bb2))
	{
		// same types...

		CircularBoundingBox* cb1 = dynamic_cast<CircularBoundingBox*>(bb1);
		CircularBoundingBox* cb2 = dynamic_cast<CircularBoundingBox*>(bb2);


		if(cb1 && cb2)
		{
			// both boxes are circ boundingboxes

			// There's a collision if (r1 + r2) > distance between centers
			// => (r1 + r2)² > (distance between centers)²

			// distance² = (x2-x1)²+(y2-y1)²

			double distanceSqrd =
						( (cb2->getCenter().getX() - cb1->getCenter().getX())
						* (cb2->getCenter().getX() - cb1->getCenter().getX()))
					+
						( (cb2->getCenter().getY() - cb1->getCenter().getY())
						* (cb2->getCenter().getY() - cb1->getCenter().getY()));

			// (sum of radii)² = (r1 + r2)²
			double sumOfRadii = cb1->getRadius() + cb2->getRadius();
			double sumOfRadiiSqrd = sumOfRadii * sumOfRadii;

			if(sumOfRadiiSqrd > distanceSqrd)
				return true;
			else
				return false;
		}
		else
			throw NotYetImplementedException();

	}
	else
		throw NotYetImplementedException();
}

bool si::CollisionDetector::aShotB(
							std::tr1::shared_ptr<Ship> a,
							std::tr1::shared_ptr<Ship> b,
							int& damage,
							int& whichBullet)
{
	for(unsigned int i = 0; i < a->fBullets.size(); i++)
	{
		// look if this bullet is hitting ship B
		if(collision(a->fBullets[i]->fBoundingBox, b->fBoundingBox))
		{
			damage = a->fBullets[i]->fDamage;
			whichBullet = i;
			return true;
		}

	}

	return false;
}





